#include "comandos.h"


/* Comparador para mantener orden de insercion */
int comparadorOrderInsercion(void* elem1, void* elem2);

/* Funcion callback que llama a evento ocurrido del Constructor
   se agrega porque no se podia setear directamente el puntero
   a la primitiva Tconstructor_eventoOcurrido ya que la firme es
   distinta(el primer parametro es TConstructo* y no void*
   No me convence esto si lo podemos mejorar joya */
int funcionCallback(const void* contexto, int evento, const void* dato){
    TConstructor* constructor = (TConstructor*)contexto;
    return Tconstructor_eventoOcurrido((void*)constructor, evento, (void*)dato);
}

/* Abre el archivo mediante su nombre y lo procesa */
int abrirProcesarArchivo(TBuscador* buscador, char* nombreArchivo){
    /*defino e inicializo las variables para manejar los errores*/
    char mensaje[MAX_DATO];
    int codigo = CODIGO_OK;
    /* Archivo a procesar */
    FILE* archivoProcesar;
    /* Constructor que se usa */
    TConstructor constructor;
    /* Parser que se usa */
    TParser parser;
    /* Lista de diccionarios que se genera desde el constructor */
    TListaSimpleOrdenada listaDiccionarios;
    /* Abre el archivo a procesar */
    archivoProcesar = fopen(nombreArchivo, "r");
    /* Se crea el constructor */
    Tconstructor_Crear(&constructor);
    /* Se crea el parser */
    TParser_Crear(&parser);
    /* Se seta la funcion callback al Parser */
    TParser_setCallback(&parser, 0, &constructor, &funcionCallback);
    /* Determina si se pudo abrir o no el archivo */
    if (archivoProcesar!=NULL){
        /* Si pudo abrir el archivo lo procesa */
        /* Mientras no se termine el archivo lo muestra linea por linea */
        while(!feof(archivoProcesar)&&(!codigo)){ /*si ya hubo un error deja de procesar el archivo*/
            /* Linea obtenida del archivo */
            char lineaArchivo[MAX_LONGITUD_LINEA];
            /* Posicion linea a procesar */
            int posicionLinea;
            /* Muestra el archivo linea a linea */
            fgets(lineaArchivo, MAX_LONGITUD_LINEA, archivoProcesar);
             /* Recorre caracter por caracter la linea leida */
            for (posicionLinea=0; posicionLinea<MAX_LONGITUD_LINEA && (lineaArchivo[posicionLinea]!=CARACTER_FIN_LINEA) && (lineaArchivo[posicionLinea]!='\0'); posicionLinea++){
                if (TParser_PushChar(&parser, lineaArchivo[posicionLinea])){
                	/*recuperarMensajeError(parser.codigoUltimoError);*/
                	TParser_getUltimoError(&parser, &codigo, mensaje);
                	printf("%s\n",mensaje);
                	TParser_terminarFlujo(&parser);
                	/* Cierra el archivo */
                	fclose(archivoProcesar);
                	return CODIGO_OK;
                }
            }
        }
        /* Crea la lista de Diccionarios desde el constructor */
        lso_Crear(&listaDiccionarios, sizeof(TDiccionario), &comparadorOrderInsercion);
        /*armo la lista de diccionarios */
        Tconstructor_ArmarLista(&constructor, &listaDiccionarios);
        /* Se procesan los tweets agregandolos al indice mediante el Buscador */
        TBuscador_indexarDiccionarios(buscador, &listaDiccionarios);
        /* Se termina el flujo del parser */
        TParser_terminarFlujo(&parser);
        /* Se destruye el Constructor */
        Tconstructor_Destruir(&constructor);
        /*libero los recursos de la lista de campos */
        lso_Vaciar(&listaDiccionarios);
        /* Cierra el archivo */
        fclose(archivoProcesar);
    }else{
        /* Se muestra por pantalla el error */
        printf("ERROR: el archivo %s no existe\n", nombreArchivo);
        /* Si no se encontro el archivo devuelve error */
        return CODIGO_ERROR_ARCHIVO_INEXISTENTE;
    }
    /* Si no ocurrio error, retorna ejecucion ok */
    return CODIGO_OK;
}

/* Ejecutar comando mediante su id */
int ejecutarComando(int idComando, char arrayArgumentos[MAX_CANTIDAD_ARGUMENTOS][MAX_DATO], TBuscador* buscador, TListaSimpleOrdenada* listaResultados){
    /* Resultado del comando */
    int resultadoEjecucion = CODIGO_OK;
    /* Dependiendo el id del comando ejecuta el que corresponda */
    if (idComando==ID_COMANDO_AGREGAR){
        resultadoEjecucion = abrirProcesarArchivo(buscador, arrayArgumentos[0]);
    }else if (idComando==ID_COMANDO_AND){
        TBuscador_interseccion(buscador, arrayArgumentos[0], listaResultados);
    }else if (idComando==ID_COMANDO_OR){
        TBuscador_union(buscador, arrayArgumentos[0], listaResultados);
    }else if (idComando==ID_COMANDO_ELIMINAR_U){
        TBuscador_borrarDiccionario(buscador, arrayArgumentos[0], NULL);
    }else if (idComando==ID_COMANDO_ELIMINAR_T){
        TBuscador_borrarDiccionario(buscador, arrayArgumentos[0], arrayArgumentos[1]);
    }else if (idComando==ID_COMANDO_OPTIMIZAR){
        TBuscador_optimizar(buscador);
    }else if (idComando==ID_COMANDO_INVALIDO){
        printf("El comando ingresado es invalido\n");
    }else if (idComando==CODIGO_ERROR_ARGUMENTOS_INVALIDOS){
        printf("Argumentos invalidos para el comando\n");
    }
    /* Devuelve codigo de OK */
    return resultadoEjecucion;
}
